package com.sojson.util.file.system.impl.minio.config;

import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import com.sojson.constant.Constant;
import com.sojson.util.init.InitUtil;

import io.minio.MinioClient;
import okhttp3.OkHttpClient;

/**
 * MiniO配置类
 *
 * @author liu
 * @date 2024-07-06
 */
//@Configuration
public class MinioConfig {

    /** 服务器地址 */
    public static final String ENDPOINT = Constant.PROPERTIES.getProperty("so.minio.endpoint");
    /** 服务器账号 */
    private static final String ACCESS_KEY = Constant.PROPERTIES.getProperty("so.minio.accessKey");
    /** 服务器密码 */
    private static final String SECRET_KEY = Constant.PROPERTIES.getProperty("so.minio.secretKey");

    public MinioConfig() {}

    //    @Bean
    public MinioClient minioClient() {
        if (ENDPOINT != null) {
            InitUtil.add("当前文件存储系统MiniO的IP为: " + ENDPOINT);
        }
        return MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY)
            .httpClient(getUnsafeOkHttpClient()).build();
    }

    public static SSLSocketFactory getSSLSocketFactory() {
        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, getTrustManager(), new java.security.SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static TrustManager[] getTrustManager() {
        return new TrustManager[] {new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) {}

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) {}

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[] {};
            }
        }};
    }

    public static X509TrustManager getX509TrustManager() {
        X509TrustManager trustManager = null;
        try {
            TrustManagerFactory trustManagerFactory =
                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore)null);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
                throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
            }
            trustManager = (X509TrustManager)trustManagers[0];
        } catch (Exception e) {
            e.printStackTrace();
        }

        return trustManager;
    }

    public static OkHttpClient getUnsafeOkHttpClient() {
        return new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).connectTimeout(60, TimeUnit.SECONDS)
            .sslSocketFactory(getSSLSocketFactory(), getX509TrustManager()).hostnameVerifier(getHostnameVerifier())
            .build();
    }

    public static HostnameVerifier getHostnameVerifier() {
        return (s, sslSession) -> true;
    }

}